package 集合.哈希.HashMap的查找问题;

import java.util.HashMap;

class Person{
    private String id;
    Person(String id){
        this.id=id;
    }

    /**
     * 几乎完美的equals()方法
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;//第一步：地址一样肯定为true
        if (o == null || getClass() != o.getClass()) return false;//第二步：比较运行时期对象的Class对象

        Person person = (Person) o;//第三步：比较属性值
        if (id != null ? !id.equals(person.id) : person.id != null) return false;

        return true;
    }
    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;//使用对象的 属性值的HashCode
    }
}
public class HashMap_Test2 {
    /*使用自定义类作为key,需要重写 类的hashcode和equals方法*/
    public static void main(String[] args) {
        HashMap<Person, String> map = new HashMap<>();
        map.put(new Person("001"),"1");
        map.put(new Person("002"),"2");
        map.put(new Person("003"),"3");
        map.put(new Person("003"),"4");

        System.out.println(map.toString());
        /**快速打印map集合*/
        for (Person mp : map.keySet()) {
            System.out.println("key = " + mp + ", value = " + map.get(mp));
        }

        System.out.println(map.get(new Person("001")));
        System.out.println(map.get(new Person("002")));
        System.out.println(map.get(new Person("003")));

        /*hash 的存取都需要 1、比较hashcode 2、equals*/
        System.out.println(new Person("1").hashCode());//
        System.out.println(new Person("1").hashCode());//重写之后两者的hashcode相同
        System.out.println(new Person("1")==new Person("1"));//为false，‘==’比较的是对象的内存地址
        System.out.println(new Person("1").equals(new Person("1")));//true，重写了equals方法
    }
}
/* map.put: 即存放元素，经历两个方法来判断是否是相同的key：HashCode()、equals()
*  map.get: 查找元素，1、计算当前需要查询元素的HashCode，获取map集合中所有的key的HashCode,得到一个HashCode链表
*                   2、遍历链表：找到相同HashCode对应的key，还没有完，通过equals()来判断当前的key和map集合中的key是否相等
*           完成这两步，才能真正的判断是否是相同的key。
*   但是所有的类的父类都是Object类，Object中的HashCode()、equals() 都是通过对象的地址来进行计算的，而new 出来的对象，它们的地址都是不同的
*   这就造成了刚才的两种情况：两个相同的对象也可以存进去、所有的查询都失败。
*
*    因此我们需要重写类的HashCode()、equals()
* */
